package com.codeoss.framework.webide.app.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.codeoss.framework.context.YunContext;
import com.codeoss.framework.util.IOUtil;
import com.codeoss.framework.webide.app.service.IAppDataHandler;
import com.codeoss.framework.webide.app.service.store.IAppDataHandlerStore;
import com.codeoss.module.ir.model.IrApplication;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

@Service
public class AppExportManager {
	@Autowired
	private ObjectMapper objectMapper;
	@Autowired
	private IAppDataHandlerStore appDataHandlerStore;
	@Value("${framework.base-path}")
	private String basePath;
	public ByteArrayOutputStream exportApp(YunContext yunContext, IrApplication irApplication) {
		InputStream is=this.getClass().getClassLoader().getResourceAsStream("com/codeoss/framework/webide/app/service/impl/appconfig.json");
		JsonNode appJsonNode=null;
		try {
			 appJsonNode=objectMapper.readTree(is);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}finally {
			IOUtil.closeInputStream(is);
		}
		String folderName = UUID.randomUUID().toString();
		File folder = new File(basePath + File.separator + "code" + File.separator + folderName);
		folder.mkdirs();
		
		PrintWriter pw = null;
		try {
			pw = new PrintWriter(
					new OutputStreamWriter(new FileOutputStream(folder + File.separator + "app_config.cfg")), true);
			pw.println("appcode=" + irApplication.getCode());
			pw.println("appname=" + irApplication.getName());
			pw.println("module_type_list="+irApplication.getModuleTypeList());
			yunContext.setAttribute("__pw__", pw);
			yunContext.setAttribute("__folder__", folder);
			
			ArrayNode tableListArrayNode=(ArrayNode)appJsonNode.get("tableList");
			for(int i=0;i<tableListArrayNode.size();i++) {
				JsonNode jsonNode=tableListArrayNode.get(i);
				String table=jsonNode.get("table").asText();
				IAppDataHandler appDataHandler=appDataHandlerStore.getAppDataHandlerByTable(yunContext, table);
				appDataHandler.dataExport(yunContext, irApplication, table);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		} finally {
			if (pw != null) {
				pw.close();
			}
		}
		
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		ZipOutputStream zos = null;
		try {
			zos = new ZipOutputStream(os);
			File fileArray[] = folder.listFiles();
			for (int i = 0; i < fileArray.length; i++) {
				byte[] buf = new byte[1024];
				File file = fileArray[i];
				zos.putNextEntry(new ZipEntry(file.getName()));

				int len;
				FileInputStream in = new FileInputStream(file);
				while ((len = in.read(buf)) != -1) {
					zos.write(buf, 0, len);
				}
				zos.closeEntry();
				in.close();
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				zos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);
			}
		}
		return os;
	}
}
